Fix output formats for the theme mod get command#456
Conversation
schlessera
left a comment
There was a problem hiding this comment.
Looks good, only minor nitpicks for the code. Also, it would be good to have at least 1 feature test covering this.
|
Oh, I will do tests by the way! Just probably not until after this week :) |
There was a problem hiding this comment.
Pull request overview
This PR refactors the wp theme mod get implementation to produce well-structured output across table, CSV, JSON, and YAML formats, particularly for nested option values, addressing malformed output reported in issue #96.
Changes:
- Introduces a recursive
mod_to_string()helper to flatten nested theme mod arrays/objects into a list of{ key, value }pairs, with special handling for booleans and empty arrays. - Adjusts table formatting to use indentation for nested keys and uses dot-notation for hierarchical keys in CSV/JSON/YAML formats, while filtering out items deemed to have “no value” in non-tabular formats.
- Updates usage of
WP_CLI\Utils\get_flag_value()via an importedUtilsalias and reuses the new formatter logic for bothgetandlist_subcommands.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // If specific mods are requested, filter out any that aren't requested. | ||
| $mods = ! empty( $args ) ? array_intersect_key( get_theme_mods(), array_flip( $args ) ) : get_theme_mods(); | ||
|
|
||
| // For unset mods, show blank value. | ||
| foreach ( $args as $mod ) { | ||
| if ( ! isset( $mods[ $mod ] ) ) { | ||
| $list[] = [ | ||
| 'key' => $mod, | ||
| 'value' => '', | ||
| ]; | ||
| // Generate the list of items ready for output. We use an initial separator that we can replace later depending on format. | ||
| $separator = '\t'; | ||
| array_walk( | ||
| $mods, | ||
| function ( $value, $key ) use ( &$mod_list, $separator ) { |
There was a problem hiding this comment.
The previous implementation added rows for requested mods that are not present in get_theme_mods() (see the old "For unset mods, show blank value." logic), which is relied on by the theme-mod.feature example for header_textcolor. With this new $mods construction and no subsequent pass over $args, requested-but-unset mods are now silently omitted from the output for all formats, changing the CLI behavior; to preserve backward compatibility you should add entries with an empty value for any requested mod that is not present in $mods (at least for the table format, and optionally for others).
| // For JSON, CSV, and YAML formats we use dot notation to show the hierarchy. | ||
| case 'csv': | ||
| case 'yaml': | ||
| case 'json': | ||
| $mod_list = array_filter( | ||
| array_map( | ||
| static function ( $item ) use ( $separator ) { | ||
| return [ | ||
| 'key' => str_replace( $separator, '.', $item['key'] ), | ||
| 'value' => $item['value'], | ||
| ]; | ||
| }, | ||
| $mod_list | ||
| ), | ||
| function ( $item ) { | ||
| return ! empty( $item['value'] ); | ||
| } | ||
| ); | ||
| break; |
There was a problem hiding this comment.
The new flattening and dot-notation logic for CSV/YAML/JSON formats introduces non-trivial behavior but currently has no dedicated acceptance tests (unlike features/theme-mod-list.feature, which covers those formats for the list subcommand). Given that issue #96 was caused by malformed non-tabular output, it would be valuable to add Behat coverage for wp theme mod get --all --format=csv|json|yaml with nested theme-mod structures to ensure this formatter behavior is exercised and guarded against regressions.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Pascal Birchler <pascal.birchler@gmail.com>
|
This is lacking tests & is breaking existing ones. Will see if I can pick this up to bring it over the finish line. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Fixes #96
I maintained but improved the space-indented formatting for the table format as folks might be using this (as per @schlessera's comment) and then fixed the other formats by using dot notation to represent each field, given the formatter needs arrays with
keyandvalue.For the table format, I opted to remove the
=>for the value to represent an array. I felt it was harder to read than simply leaving the value blank and letting the indent do the visual work.For all formats booleans and empty arrays are represented by a string (e.g.
[empty array]. There may be a better way to represent these, and I did considervar_export()but others may have better ideas.When specific mods are requested but don't exist, they are included in the output with
nullas the value except for CSV output which just has an empty string.New Behat tests are included for each of the formats (table, csv, json, yaml).
Here are some examples of the new output: